home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 January / macformat-020.iso / Shareware City / Developers / apps.to.go / Kibitz / CMRookMate.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-06  |  7.2 KB  |  320 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** File:        cmrookmate.c
  5. ** Written by:  Eric Soldan
  6. **
  7. ** Copyright © 1990-1992 Apple Computer, Inc.
  8. ** All rights reserved. */
  9.  
  10.  
  11.  
  12. /*****************************************************************************/
  13.  
  14.  
  15.  
  16. #include "Kibitz.h"                /* Get the Kibitz includes/typedefs, etc.    */
  17. #include "KibitzCommon.h"        /* Get the stuff in common with rez.        */
  18. #include "Kibitz.protos"        /* Get the prototypes for Kibitz.            */
  19.  
  20.  
  21.  
  22. /*****************************************************************************/
  23.  
  24.  
  25.  
  26. extern short    gPieceLoc;
  27.  
  28.  
  29.  
  30. /*****************************************************************************/
  31.  
  32.  
  33.  
  34. #pragma segment Chess
  35. short    RookMate(FileRecHndl game)
  36. {
  37.     short            color, myKingLoc, opKingLoc, pieceLoc;
  38.     short            mkr, mkc, okr, okc, pr, pc;
  39.     short            dr, dc, absdr, absdc;
  40.     short            from, to, minVal, minMove;
  41.     short            rspin;
  42.     Boolean            hflip, onEdge;
  43.     MoveListHndl    moves;
  44.     short            num, move;
  45.  
  46.     GenerateLegalMoves(game);
  47.     num   = (*game)->doc.numLegalMoves;
  48.     moves = (*game)->doc.legalMoves;
  49.  
  50.     color = WhosMove(game);
  51.     myKingLoc = (*game)->doc.king[color].kingLoc;
  52.     opKingLoc = (*game)->doc.king[1 - color].kingLoc;
  53.     pieceLoc  = gPieceLoc;
  54.  
  55.     GetDeltas(myKingLoc, pieceLoc, &dr, &dc, &absdr, &absdc);
  56.     if ((absdr > 1) || (absdc > 1)) {            /* If piece not next to king... */
  57.         GetRowCol(opKingLoc, &okr, &okc);
  58.         onEdge = false;
  59.         if ((!okr) || (okr == 7)) onEdge = true;
  60.         if ((!okc) || (okc == 7)) onEdge = true;
  61.         for (minVal = 16, move = 0; move < num; ++move) {
  62.             from = (**moves)[move].moveFrom;
  63.             to   = (**moves)[move].moveTo;
  64.             if (from == pieceLoc) {            /* If piece move... */
  65.                 GetDeltas(to, opKingLoc, &dr, &dc, &absdr, &absdc);
  66.                 if ((onEdge) && (absdr < 3) && (absdc < 3)) continue;
  67.                     /* We don't want to stalemate the guy while trying to get
  68.                     ** our piece close to our king. */
  69.                 if ((absdr < 2) && (absdc < 2)) continue;
  70.                     /* We don't want to get our piece captured either. */
  71.                 GetDeltas(to, myKingLoc, &dr, &dc, &absdr, &absdc);
  72.                 if (minVal > (absdr + absdc)) {
  73.                     minVal = absdr + absdc;
  74.                     minMove = move;
  75.                 }
  76.             }
  77.         }
  78.         return(minMove);
  79.     }
  80.  
  81.     for (rspin = 0;; ++rspin) {        /* Rotate until opponent king is above us. */
  82.         GetDeltas(myKingLoc, opKingLoc, &dr, &dc, &absdr, &absdc);
  83.         if (dr > 1) break;
  84.         RSpinPosition(&myKingLoc);
  85.         RSpinPosition(&opKingLoc);
  86.         RSpinPosition(&pieceLoc);
  87.     }
  88.         
  89.     GetDeltas(myKingLoc, opKingLoc, &dr, &dc, &absdr, &absdc);
  90.     hflip = false;
  91.     if (dc < 0) hflip = true;        /* Position opponent king left of ours. */
  92.     if (!dc) {
  93.         GetDeltas(pieceLoc, opKingLoc, &dr, &dc, &absdr, &absdc);
  94.         if (dc < 0) hflip = true;
  95.     }
  96.     if (hflip) {
  97.         HFlipPosition(&myKingLoc);
  98.         HFlipPosition(&opKingLoc);
  99.         HFlipPosition(&pieceLoc);
  100.     }
  101.  
  102.     GetRowCol(myKingLoc, &mkr, &mkc);
  103.     GetRowCol(opKingLoc, &okr, &okc);
  104.     GetRowCol(pieceLoc,  &pr,  &pc);
  105.  
  106.     from = pieceLoc;        /* Default that we will move the piece. */
  107.     switch (myKingLoc - pieceLoc) {
  108.         case -11:
  109.             if (mkc < 2) {        /* myKing too close to left edge. */
  110.                 to = (from = myKingLoc) + 1;
  111.                 break;
  112.             }
  113.             to = from - 20;        /* opKing at least 2 rows above, so cut it off. */
  114.             break;
  115.         case -10:
  116.             if (mkc < 2) {        /* myKing too close to left edge. */
  117.                 to = (from = myKingLoc) + 1;
  118.                 break;
  119.             }
  120.             if (mkc == 7) {        /* myKing on right edge, so move piece left. */
  121.                 to = from - 1;
  122.                 break;
  123.             }
  124.             if (mkc - okc < 2) {    /* opKing above or just 1 left, so move piece right */
  125.                 to = from + 1;        /* to prevent opKing from getting away. */
  126.                 break;
  127.             }
  128.             to = from - 1;        /* opKing left of us enough to cut it off on the */
  129.             break;                /* left side of myKing. */
  130.         case -9:
  131.             if (mkc == okc) {    /* opKing is above myKing. */
  132.                 to = from + 2;    /* Cut the king off from moving right. */
  133.                 break;
  134.             }
  135.             to = from - 10;        /* opKing is 2 rows above myKing, so just slide the piece up. */
  136.             break;
  137.         case -1:
  138.             if (mkr == 7) {        /* myKing on bottom edge, so move piece up. */
  139.                 to = from - 10;
  140.                 break;
  141.             }
  142.             to = from - 10;        /* opKing at least 2 rows above myKing, so move piece up. */
  143.             break;
  144.         case 1:
  145.             if (mkc == okc) {        /* If opKing is above us, we punt. */
  146.                 if (mkr == 7) {
  147.                     to = from - 10;        /* If at bottom, move piece up 1. */
  148.                     break;
  149.                 }
  150.                 to = from + 10;            /* Move piece down 1. */
  151.                 break;
  152.             }
  153.             if ((mkr == 2) && (mkc == 2)) {        /* Leads to mate in 1 or 2 for rook. */
  154.                 to = (from = myKingLoc) - 10;
  155.                 break;
  156.             }
  157.             if ((mkr > 2) || (mkc == 2)) {
  158.                 if ((mkr + okr) & 0x01) {
  159.                     to = (from = myKingLoc) - 10;
  160.                     break;
  161.                 }
  162.             }
  163.             to = from - 10;
  164.             break;
  165.         case 9:
  166.             if ((mkc == 1) && (!okc)) {
  167.                 to = from - 1;
  168.                 break;
  169.             }
  170.             if (!mkc) {            /* myKing on left edge. */
  171.                 to = (from = myKingLoc) + 1;
  172.                 break;
  173.             }
  174.             if (mkc == okc) {
  175.                 if ((mkr - okr) == 2) {
  176.                     to = (from = myKingLoc) + 1;
  177.                     break;
  178.                 }
  179.                 if ((mkr - okr) > 2) {
  180.                     to = (from = myKingLoc) - 10;
  181.                     break;
  182.                 }
  183.             }
  184.             to = from - 1;
  185.             if (mkc - okc > 1) --to;
  186.             break;
  187.         case 10:
  188.             if ((mkr == 2) && (mkc == 2)) {
  189.                 if (mkr == 2) {            /* Leads to mate in 1 or 2 for rook. */
  190.                     to = (from = myKingLoc) - 1;
  191.                     break;
  192.                 }
  193.             }
  194.             if ((mkr == 3) && (mkc == 2)) {
  195.                 if ((okr == 1) && (okc == 1)) {
  196.                     to = (from = myKingLoc) - 9;
  197.                     break;
  198.                 }
  199.                 if (!okr) {
  200.                     to = (from = myKingLoc) - 11;
  201.                     break;
  202.                 }
  203.                 to = from - 1;
  204.                 break;
  205.             }
  206.             if (mkc < 2) {        /* myKing too close to left edge. */
  207.                 to = (from = myKingLoc) + 1;
  208.                 if (mkr > 2) to -= 10;
  209.                 break;
  210.             }
  211.             if ((mkc - okc) == 1) {
  212.                 to = (from = myKingLoc) - 1;
  213.                 if ((mkr - okr) > 2) to -= 10;
  214.                 break;
  215.             }
  216.             to = from - 1;
  217.             break;
  218.         case 11:
  219.             if ((mkr == 2) && (mkc == 2)) {
  220.                 to = from + 10;
  221.                 break;
  222.             }
  223.             if (mkc == okc) {
  224.                 to = from + 1;
  225.                 if (mkc < 7) ++to;
  226.                 break;
  227.             }
  228.             if (mkc > 2) {
  229.                 to = (from = myKingLoc) - 1;
  230.                 break;
  231.             }
  232.             to = (from = myKingLoc) - 10;
  233.             break;
  234.     }
  235.  
  236.     if (hflip) {
  237.         HFlipPosition(&from);
  238.         HFlipPosition(&to);
  239.     }
  240.  
  241.     for (; rspin < 4; ++rspin) {        /* Rotate some more to make 4. */
  242.         RSpinPosition(&from);
  243.         RSpinPosition(&to);
  244.     }
  245.         
  246.     for (move = 0; move < num; ++move)
  247.         if ((from == (**moves)[move].moveFrom) && (to == (**moves)[move].moveTo)) return(move);
  248.  
  249.     return(-1);
  250.         
  251. }
  252.  
  253.  
  254.  
  255. /*****************************************************************************/
  256.  
  257.  
  258.  
  259. #pragma segment Chess
  260. void    GetRowCol(short pos, short *row, short *col)
  261. {
  262.     *row = (pos - START_IBNDS) / 10;
  263.     *col = pos - START_IBNDS - *row * 10;
  264. }
  265.  
  266.  
  267.  
  268. /*****************************************************************************/
  269.  
  270.  
  271.  
  272. #pragma segment Chess
  273. void    GetDeltas(short pos1, short pos2, short *dr, short *dc, short *absdr, short *absdc)
  274. {
  275.     short    r1, c1, r2, c2;
  276.  
  277.     GetRowCol(pos1, &r1, &c1);
  278.     GetRowCol(pos2, &r2, &c2);
  279.     *dr = r1 - r2;
  280.     *dc = c1 - c2;
  281.  
  282.     if ((*absdr = *dr) < 0) *absdr = -*absdr;
  283.     if ((*absdc = *dc) < 0) *absdc = -*absdc;
  284. }
  285.  
  286.  
  287.  
  288. /*****************************************************************************/
  289.  
  290.  
  291.  
  292. #pragma segment Chess
  293. void    RSpinPosition(short *pos)
  294. {
  295.     short    oldr, oldc, newr, newc;
  296.  
  297.     GetRowCol(*pos, &oldr, &oldc);
  298.     newr = oldc;
  299.     newc = 7 - oldr;
  300.     *pos = START_IBNDS + 10 * newr + newc;
  301. }
  302.  
  303.  
  304.  
  305. /*****************************************************************************/
  306.  
  307.  
  308.  
  309. #pragma segment Chess
  310. void    HFlipPosition(short *pos)
  311. {
  312.     short    r, c;
  313.  
  314.     GetRowCol(*pos, &r, &c);
  315.     *pos = START_IBNDS + 10 * r + (7 - c);
  316. }
  317.  
  318.  
  319.  
  320.